package edu.pdx.LAMA.AndroidCourse.ModelLayer;

// http://stackoverflow.com/questions/5762389/how-to-view-data-saved-in-android-databasesqlite

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.CalendarContract.CalendarAlerts;
import android.util.Log;

public class EventService extends SQLiteOpenHelper{

	private static final String TAG = "edu.pdx.LAMA.AndroidCourse.ModelLayer.tag";
	// Setting the current version
	private static final int DATABASE_VERSION = 9;

	// Setting up a name for the db
	private static final String DATABASE_NAME = "SchedulerEventDB";

	// Creating the first table now
	private static final String TABLE_EVENT_DETAILS = "SchEventDetails";
	private static final String TABLE_CATEGORIES = "CategoryDetails";
	private static final String TABLE_DAILY_EVENTS = "DailyEventsDetails";

	// Creating the column names
	private static final String KEY_ID = "event_id";
	private static final String EVENT_DATE = "event_date";
	private static final String EVENT_TITLE = "event_title";
	private static final String EVENT_START_TIME = "event_start_time";
	private static final String EVENT_END_TIME = "event_end_time";
	private static final String EVENT_PRIORITY = "event_priority";
	private static final String EVENT_LOCATION = "event_location";
	private static final String EVENT_CATEGORY = "event_category";
	private static final String EVENT_ALARM = "event_alarm";

	// Second table column names
	private static final String CATEGORY_NAME = "category_name";

	// query related strings
	private static final String CREATE_TABLE_STRING = "CREATE TABLE ";
	private static final String DROP_TABLE_STRING = "DROP TABLE IF EXISTS ";

	public EventService(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
		// TODO Auto-generated constructor stub
	}

	public ArrayList<EventDetails> getDailyEvent() {
		ArrayList<EventDetails> arrayList = new ArrayList<EventDetails>();
		EventDetails details = new EventDetails();
		details.setID(0001);
		details.setDate("29/10/2014");
		details.setAlarmTime(10);
		details.setCategory("health");
		details.setEndTime("16:10");
		details.setStartTime("16:20");
		details.setLocation("Hillsboro");
		details.setPriority("Low");
		details.setTitle("Meeting 1");
		arrayList.add(details);

		details = new EventDetails();
		details.setID(0002);
		details.setDate("9/9/2014");
		details.setAlarmTime(15);
		details.setCategory("work");
		details.setEndTime("16:20");
		details.setStartTime("16:30");
		details.setLocation("Portland");
		details.setPriority("Medium");
		details.setTitle("Meeting 2");
		arrayList.add(details);

		return arrayList;
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL(CREATE_TABLE_STRING+TABLE_EVENT_DETAILS+"("
				+KEY_ID+" INTEGER PRIMARY KEY,"
				+EVENT_DATE+" TEXT,"
				+EVENT_TITLE+" TEXT,"
				+EVENT_START_TIME+" TEXT,"
				+EVENT_END_TIME+" TEXT,"
				+EVENT_PRIORITY+" TEXT,"
				+EVENT_LOCATION+" TEXT,"
				+EVENT_CATEGORY+" TEXT,"
				+EVENT_ALARM+" INTEGER"+")");

		db.execSQL(CREATE_TABLE_STRING+TABLE_CATEGORIES+"("
				+CATEGORY_NAME+" TEXT PRIMARY KEY)");

		db.execSQL(CREATE_TABLE_STRING+TABLE_DAILY_EVENTS+"("
				+KEY_ID+" INTEGER PRIMARY KEY,"
				+EVENT_TITLE+" TEXT,"
				+EVENT_START_TIME+" TEXT,"
				+EVENT_END_TIME+" TEXT,"
				+EVENT_PRIORITY+" TEXT,"
				+EVENT_LOCATION+" TEXT,"
				+EVENT_CATEGORY+" TEXT)");

		try{
			db.execSQL("INSERT INTO "+TABLE_CATEGORIES+" VALUES ("+"'Work')");
			db.execSQL("INSERT INTO "+TABLE_CATEGORIES+" VALUES ("+"'Health')");
			db.execSQL("INSERT INTO "+TABLE_CATEGORIES+" VALUES ("+"'Leisure')");
		} catch (Exception e){
			Log.d(TAG, "error inserting into the categories table");
		}

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		// Upgrade is basically when you want to make changes to the table structure as a whole
		// or do something like that
		db.execSQL(DROP_TABLE_STRING+TABLE_EVENT_DETAILS);
		db.execSQL(DROP_TABLE_STRING+TABLE_CATEGORIES);
		db.execSQL(DROP_TABLE_STRING+TABLE_DAILY_EVENTS);
		// create tables again
		onCreate(db);
	}

	public void addEvent(EventDetails eventDetails){
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues contentValues = new ContentValues();

		Log.d(TAG, eventDetails.getID()+" "+eventDetails.getDate()+" "+eventDetails.getTitle()+" "+eventDetails.getStartTime()+" "+eventDetails.getCategory());
		// Setting up the values to be persisted
		contentValues.put(KEY_ID, eventDetails.getID());
		contentValues.put(EVENT_DATE, eventDetails.getDate());
		contentValues.put(EVENT_TITLE, eventDetails.getTitle());
		contentValues.put(EVENT_START_TIME, eventDetails.getStartTime());
		contentValues.put(EVENT_END_TIME, eventDetails.getEndTime());
		contentValues.put(EVENT_PRIORITY, eventDetails.getPriority());
		contentValues.put(EVENT_LOCATION, eventDetails.getLocation());
		contentValues.put(EVENT_CATEGORY, eventDetails.getCategory());
		contentValues.put(EVENT_ALARM, eventDetails.getAlarmTime());

		db.insert(TABLE_EVENT_DETAILS, null, contentValues);
		db.close();
	}

	public void addDailyEvent(EventDetails eventDetails){
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues contentValues = new ContentValues();

		Log.d(TAG, eventDetails.getID()+" "+eventDetails.getDate()+" "+eventDetails.getTitle()+" "+eventDetails.getStartTime()+" "+eventDetails.getCategory());
		// Setting up the values to be persisted
		contentValues.put(KEY_ID, eventDetails.getID());
		contentValues.put(EVENT_TITLE, eventDetails.getTitle());
		contentValues.put(EVENT_START_TIME, eventDetails.getStartTime());
		contentValues.put(EVENT_END_TIME, eventDetails.getEndTime());
		contentValues.put(EVENT_PRIORITY, eventDetails.getPriority());
		contentValues.put(EVENT_LOCATION, eventDetails.getLocation());
		contentValues.put(EVENT_CATEGORY, eventDetails.getCategory());

		db.insert(TABLE_DAILY_EVENTS, null, contentValues);
		db.close();
	}

	public long addCategory(String categoryName) {
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues contentValues = new ContentValues();
		long a=909090;
		boolean returnVal=true;
		try {
			contentValues.put(CATEGORY_NAME, categoryName);
			a = db.insert(TABLE_CATEGORIES, null, contentValues);
			//returnVal = true;
		} catch (Exception e) {
			// TODO: handle exception
			returnVal = false;
		} finally {
			db.close();
		}
		Log.d(TAG, ((Boolean)returnVal).toString());
		Log.d(TAG, ((Long)a).toString());
		return a;
	}

	public EventDetails getEventDetails(int id){
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor cursor = db.query(TABLE_EVENT_DETAILS, new String[] { KEY_ID,
				EVENT_DATE, EVENT_TITLE, EVENT_START_TIME, EVENT_END_TIME,
				EVENT_PRIORITY, EVENT_LOCATION, EVENT_CATEGORY, EVENT_ALARM },
				KEY_ID+"=?", new String[] { String.valueOf(id) },
				null, null, null, null);
		if (cursor!=null){
			cursor.moveToFirst();
		}

		EventDetails details = new EventDetails();
		details.setID(cursor.getInt(0));
		details.setDate(cursor.getString(1));
		details.setTitle(cursor.getString(2));
		details.setStartTime(cursor.getString(3));
		details.setEndTime(cursor.getString(4));
		details.setPriority(cursor.getString(5));
		details.setLocation(cursor.getString(6));
		details.setCategory(cursor.getString(7));
		details.setAlarmTime(cursor.getInt(8));
		details.setDailyEvent(false);

		cursor.close();
		db.close();
		return details;
	}

	public List<EventDetails> getDatewiseEvents(String date){
		List<EventDetails> eventList = new ArrayList<EventDetails>();

		// Creating a select query with a where clause which would get us events for the current date
		String selectQuery = "SELECT  * FROM " + TABLE_EVENT_DETAILS+ " WHERE "+EVENT_DATE+"='"+date+"'";
		Log.d(TAG, selectQuery);
		SQLiteDatabase db = this.getWritableDatabase();
		Cursor cursor = db.rawQuery(selectQuery, null);

		if (cursor.moveToFirst()) {
			Log.d(TAG, "We are inside the cursor");
			do {
				EventDetails details = new EventDetails();
				details.setID(cursor.getInt(0));
				details.setDate(cursor.getString(1));
				details.setTitle(cursor.getString(2));
				details.setStartTime(cursor.getString(3));
				details.setEndTime(cursor.getString(4));
				details.setPriority(cursor.getString(5));
				details.setLocation(cursor.getString(6));
				details.setCategory(cursor.getString(7));
				details.setAlarmTime(cursor.getInt(8));
				details.setDailyEvent(false);
				eventList.add(details);
			} while(cursor.moveToNext());
		}
		cursor.close();
		db.close();
		// we have to sort event list as per date
		int size = eventList.size();
		Log.d(TAG, "size of list: "+size);
		EventDetails[] ed = new EventDetails[size];
		Iterator<EventDetails> iter = eventList.iterator();
		int i = 0;
		while (iter.hasNext()){
			ed[i] = iter.next();
			i++;
		}
		// call bubble sort
		ed = this.bubbleSort(ed);
		Log.d(TAG, "size of list 2: "+ed.length);
		ArrayList<EventDetails> newList = new ArrayList<EventDetails>();
		Log.d(TAG, "Length of Array: "+ed);
		for (int l = 0;l<=ed.length-1;l++){
			newList.add(ed[l]);
		}
		Log.d(TAG, "size of list being returned "+newList.size());
		return newList;
	}

	public List<EventDetails> getDailyEvents(){
		List<EventDetails> eventList = new ArrayList<EventDetails>();

		// Creating a select query with a where clause which would get us events for the current date
		String selectQuery = "SELECT  * FROM " + TABLE_DAILY_EVENTS;
		Log.d(TAG, selectQuery);
		SQLiteDatabase db = this.getWritableDatabase();
		Cursor cursor = db.rawQuery(selectQuery, null);

		if (cursor.moveToFirst()) {
			Log.d(TAG, "We are getting the daily events");
			do {
				EventDetails details = new EventDetails();
				details.setID(cursor.getInt(0));
				Calendar c = Calendar.getInstance();
				int d = c.get(Calendar.DAY_OF_MONTH);
				int m = c.get(Calendar.MONTH);
				int y = c.get(Calendar.YEAR);
				details.setDate(d+"/"+m+"/"+y);
				details.setTitle(cursor.getString(1));
				details.setStartTime(cursor.getString(2));
				details.setEndTime(cursor.getString(3));
				details.setPriority(cursor.getString(4));
				details.setLocation(cursor.getString(5));
				details.setCategory(cursor.getString(6));
				details.setAlarmTime(0);
				details.setDailyEvent(true);
				eventList.add(details);
			} while(cursor.moveToNext());
		}
		cursor.close();
		db.close();
		///////////////////////////////////////////////
		// we have to sort event list as per date
				int size = eventList.size();
				EventDetails[] ed = new EventDetails[size];
				Iterator<EventDetails> iter = eventList.iterator();
				int i = 0;
				while (iter.hasNext()){
					ed[i] = iter.next();
					i++;
				}
				// call bubble sort
				ed = this.bubbleSort(ed);
				ArrayList<EventDetails> newList = new ArrayList<EventDetails>();
				//Log.d(TAG, "length of ")
				for (int l =0;l<=ed.length-1;l++){
					newList.add(ed[l]);
				}
		///////////////////////////////////////////////
		
		return newList;
	}

	public int getDailyEventCount(String date){
		String count = "SELECT  * FROM " + TABLE_EVENT_DETAILS+ " WHERE "+EVENT_DATE+"="+date;
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor cursor = db.rawQuery(count, null);
		cursor.close();
		db.close();

		return cursor.getCount(); 
	}

	public ArrayList<Integer> getAllDailyEventIds(){
		String selectQuery = "SELECT  * FROM " + TABLE_DAILY_EVENTS;
		Log.d(TAG, selectQuery);
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor cursor = db.rawQuery(selectQuery, null);

		ArrayList<Integer> idList = new ArrayList<Integer>();
		if (cursor.moveToFirst()) {
			Log.d(TAG, "We are getting the daily events");
			do {
				idList.add(cursor.getInt(0));
			} while(cursor.moveToNext());
		}
		cursor.close();
		db.close();
		return idList;
	}

	public ArrayList<Integer> getEventIds(){
		String selectQuery = "SELECT  * FROM " + TABLE_EVENT_DETAILS;
		Log.d(TAG, selectQuery);
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor cursor = db.rawQuery(selectQuery, null);

		ArrayList<Integer> idList = new ArrayList<Integer>();
		if (cursor.moveToFirst()) {
			Log.d(TAG, "We are getting the daily events");
			do {
				idList.add(cursor.getInt(0));
			} while(cursor.moveToNext());
		}
		cursor.close();
		db.close();
		return idList;
	}

	public int updateEvent(EventDetails details){
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues contentValues = new ContentValues();

		// Setting up the values to be persisted
		//contentValues.put(KEY_ID, details.getID());
		contentValues.put(EVENT_DATE, details.getDate());
		contentValues.put(EVENT_TITLE, details.getTitle());
		contentValues.put(EVENT_START_TIME, details.getStartTime());
		contentValues.put(EVENT_END_TIME, details.getEndTime());
		contentValues.put(EVENT_PRIORITY, details.getPriority());
		contentValues.put(EVENT_LOCATION, details.getLocation());
		contentValues.put(EVENT_CATEGORY, details.getCategory());
		contentValues.put(EVENT_ALARM, details.getAlarmTime());

		return db.update(TABLE_EVENT_DETAILS, contentValues, KEY_ID+" = ?", new String[] { String.valueOf(details.getID())});
	}

	public int updateDailyEvent(EventDetails details){
		SQLiteDatabase db = this.getWritableDatabase();
		ContentValues contentValues = new ContentValues();

		// Setting up the values to be persisted
		//contentValues.put(KEY_ID, details.getID());
		contentValues.put(EVENT_TITLE, details.getTitle());
		contentValues.put(EVENT_START_TIME, details.getStartTime());
		contentValues.put(EVENT_END_TIME, details.getEndTime());
		contentValues.put(EVENT_PRIORITY, details.getPriority());
		contentValues.put(EVENT_LOCATION, details.getLocation());
		contentValues.put(EVENT_CATEGORY, details.getCategory());

		return db.update(TABLE_EVENT_DETAILS, contentValues, KEY_ID+" = ?", new String[] { String.valueOf(details.getID())});
	}

	public void deleteEvent(int id){
		SQLiteDatabase db = this.getWritableDatabase();
		db.delete(TABLE_EVENT_DETAILS, KEY_ID+" = ?", new String[] { String.valueOf(id)});
		db.close();
	}

	public void deleteDailyEvent(int id){
		Log.d(TAG, "deleting daily event");
		SQLiteDatabase db = this.getWritableDatabase();
		db.delete(TABLE_DAILY_EVENTS, KEY_ID+" = ?", new String[] { String.valueOf(id)});
		db.close();
	}

	public int getMaxID(){
		SQLiteDatabase db = this.getWritableDatabase();
		String query = "SELECT  MAX(event_id) FROM " + TABLE_EVENT_DETAILS;
		Cursor cursor = db.rawQuery(query, null);

		if (cursor!=null){
			cursor.moveToFirst();
			return cursor.getInt(0);
		} else {
			return 0;
		}
	}

	public int getDailyEventMaxID(){
		SQLiteDatabase db = this.getWritableDatabase();
		String query = "SELECT  MAX(event_id) FROM " + TABLE_DAILY_EVENTS;
		Cursor cursor = db.rawQuery(query, null);

		if (cursor!=null){
			cursor.moveToFirst();
			//Log.d(TAG, "get daily max id returning some id");
			if (cursor.getInt(0)==0){
				return 1000000;
			}
			else{
				return cursor.getInt(0); 
			}
		} else {
			return 1000000;
		}
	}

	public ArrayList<String> getCategories(){
		SQLiteDatabase db = this.getWritableDatabase();
		String query = "SELECT  * FROM " + TABLE_CATEGORIES;
		Cursor cursor = db.rawQuery(query, null);
		ArrayList<String> categoryList = new ArrayList<String>();
		if (cursor.moveToFirst()) {
			Log.d(TAG, "We are inside the cursor");
			do {
				categoryList.add(cursor.getString(0));
			} while(cursor.moveToNext());
		}
		cursor.close();
		db.close();

		return categoryList;
	}

	public EventDetails[] bubbleSort(EventDetails[] dets){
		int n = dets.length;
		int k;
		String[] startString1;
		String[] startString2;
		for (int m = n; m >= 0; m--) {
			for (int i = 0; i < n - 1; i++) {
				k = i + 1;
				// Getting the initial element in the array
				startString1 = dets[i].getStartTime().split(":");
				startString1[0] = this.appenderFunct(startString1[0]);
				startString1[1] = this.appenderFunct(startString1[1]);
				String ss1 = startString1[0]+"."+startString1[1];
				Double ss1d = Double.parseDouble(ss1);
				//startTimeIn1 = Integer.parseInt(startString1);
				
				startString2 = dets[k].getStartTime().split(":");
				startString2[0] = this.appenderFunct(startString2[0]);
				startString2[1] = this.appenderFunct(startString2[1]);
				
				String ss2 = startString2[0]+"."+startString2[1];
				Double ss2d = Double.parseDouble(ss2);

				// Getting the second element in the array
				//startString2 = dets[k].getStartTime().split(":");
				//startTimeIn2 = Integer.parseInt(startString2);
				if (ss1d > ss2d) {
					swapNumbers(i, k, dets);
				}
			}
			//printNumbers(array);
			// output should be ready here
		}
		return dets;
	}

	private void swapNumbers(int i, int j, EventDetails[] array) {

		EventDetails temp;
		temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
	
	private String appenderFunct(String a){
		if (a.length()==1){
			a="0"+a;
		}
		return a;
	}
}
